
use rsa::{RSAPrivateKey, PaddingScheme};
use rsa::Hash;

use crypto::sha2::Sha256;
use crypto::digest::Digest;
use std::iter::repeat;

pub enum HashType {
    Sha1,
    Sha256
}

/// RSA签名
///
/// - content: 签名内容
/// - private_key: 私钥，PKCS#1
/// - hash_type: hash类型
///
/// # Examples
///
/// ```
/// use sdk::sign::{SignUtil, HashType};
///
/// let content = "123";
/// let private_key = "your private key";
/// let sign = SignUtil::rsa_sign(content, private_key, HashType::Sha256);
///
/// println!("sign:{}", sign);
/// ```
/// return: 返回base64字符串
pub fn rsa_sign(content: &str, hash_type: HashType) -> String {
    let private_key="
MIIBVQIBADANBgkqhkiG9w0BAQEFAASCAT8wggE7AgEAAkEAzqnbdnGo4kxrgEtX
PIe/xWw+xiZFYDfCDl7VRQUnd1JJZcxKGKSc34ZRjVhC9xYAYyDjCa3YXhJ4NENm
0xM0IwIDAQABAkEAv/C6R/Ogay2W2n0e9LUPw4iZdOeun4Kp1Tb21TfIQ+SZa+xD
ov660x+ceRS3ehYgEKHcuiS3igiYT5bArm71gQIhAO/jh4KZpxNVEpxd/8e3n7du
LVSrtBrCnyO0ecQO02yTAiEA3IsTtSUcRAk42EIzFLcJBobipJuCUmXM68pNSzJG
ZDECIQDRYTT75wUPOKff16PTPBCp1/608pFm8gxY68OEPrSHBQIgDyIX8xkdzGlZ
ljVMrgI1Q1ZkHOly0tabbh6OmTdU7zECICU4LP17KSJLttThmZ3289dlgJwAn3ul
7UeYyKv/YYyM";


    // 格式化私钥
    let der_encoded = private_key
        .lines()
        .filter(|line| !line.starts_with("-"))
        .fold(String::new(), |mut data, line| {
            data.push_str(&line);
            data
        });
    let der_bytes = base64::decode(der_encoded).expect("failed to decode base64 content");
    // 获取私钥对象
    // let private_key = RSAPrivateKey::from_pkcs1(&der_bytes).expect("failed to parse key");
    let private_key = RSAPrivateKey::from_pkcs8(&der_bytes).expect("failed to parse key");

    // 创建一个Sha256对象
    let mut hasher = Sha256::new();
    // 对内容进行摘要
    hasher.input_str(content);
    // 将摘要结果保存到buf中
    let mut buf: Vec<u8> = repeat(0).take((hasher.output_bits()+7)/8).collect();
    hasher.result(&mut buf);

    // 对摘要进行签名
    let hash;
    match hash_type {
        HashType::Sha1 => hash = Hash::SHA1,
        HashType::Sha256 => hash = Hash::SHA2_256
    }
    let sign_result = private_key.sign(PaddingScheme::PKCS1v15Sign {hash: Option::from(hash) }, &buf);
    // 签名结果转化为base64
    let vec = sign_result.expect("create sign error for base64");

    base64::encode(vec)
}
